package com.xjscrm.server.service.grouppull.impl;

import com.alibaba.fastjson.JSONObject;
import com.uzai.mobile.collect.api.MicaTopics;
import com.uzai.mobile.collect.api.dto.MicaTransDto;
import com.uzai.mobile.collect.api.dto.MicaTriggerDto;
import com.uzai.mobile.collect.api.dto.msg.MicaFriendTalkMsg;
import com.uzai.mobile.collect.api.dto.msg.consertoserver.MicaCustomerAddTagMsg;
import com.uzai.mobile.collect.api.dto.trigger.group.MicaTriggerGroupAddMsg;
import com.uzai.mobile.collect.api.dto.trigger.talk.MicaTalkContentTextMsg;
import com.uzai.mobile.collect.api.enums.MicaMsgSource;
import com.uzai.mobile.collect.api.enums.MicaTalkMsgType;
import com.uzai.mobile.collect.api.enums.MicaTriggerType;
import com.uzai.trace.TraceGenerate;
import com.xjscrm.common.entity.*;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.vo.grouppull.GroupPullData;
import com.xjscrm.common.vo.grouppull.GroupPullMsgData;
import com.xjscrm.common.vo.grouppull.GroupRule;
import com.xjscrm.common.vo.operatorplandevice.OperatorPlanDeviceRule;
import com.xjscrm.server.biz.mq.producer.SendMsgProducer;
import com.xjscrm.server.common.util.DeviceTools;
import com.xjscrm.server.common.util.Functions;
import com.xjscrm.server.common.util.SleepTimeTools;
import com.xjscrm.server.enums.LimitRedisCacheKeyEnum;
import com.xjscrm.server.mapper.*;
import com.xjscrm.server.service.grouppull.GroupPullConfigService;
import com.xjscrm.server.service.grouppull.GroupPullDataService;
import com.xjscrm.server.service.msg.MsgSendService;
import com.xjscrm.server.vo.device.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 拉群管理
 *
 * @author makejava
 * @since 2024-03-01 17:01:12
 */
@Slf4j
@Service
public class GroupPushConfigServiceImpl implements GroupPullConfigService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SendMsgProducer sendMsgProducer;
    @Autowired
    private WwDeviceMapper wwDeviceMapper;
    @Autowired
    private WwGroupMapper wwGroupMapper;
    @Autowired
    private WwGroupMemberMapper wwGroupMemberMapper;
    @Autowired
    private WwGroupTagsRelationMapper wwGroupTagsRelationMapper;
    @Autowired
    private WwCustomerTagsMapper wwCustomerTagsMapper;
    @Autowired
    private WwCustomerMapper wwCustomerMapper;
    @Autowired
    private GroupPullConfigDeviceMapper groupPullConfigDeviceMapper;
    @Autowired
    private GroupPullConfigMapper groupPullConfigMapper;
    @Autowired
    private GroupPullDataService groupPullDataService;
    @Autowired
    private WwTagsMapper wwTagsMapper;
    @Autowired
    private MsgSendService msgSendService;
    @Autowired
    private WwCustomerBlacklistMapper wwCustomerBlacklistMapper;

    /**
     * 关键词拉群
     *
     * @param micaTransDto 客户往机器人发送聊天消息
     * @return 实例对象
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void groupPushByKeyword(MicaTransDto micaTransDto) {
        try {
            log.info("--监控系统日志--开始--");

            MicaFriendTalkMsg micaFriendTalkMsg = JSONObject.parseObject(micaTransDto.getData().toString(), MicaFriendTalkMsg.class);
            if (micaFriendTalkMsg == null) {
                return;
            }
            //只支持私聊
            if (micaFriendTalkMsg.getGroup()) {
                return;
            }

            //发送者微信id
            String sendWxId = micaFriendTalkMsg.getSendWxId();
            //发送者微信昵称
            String sendNickName = micaFriendTalkMsg.getSendNickName();
            if (StringUtils.isBlank(sendWxId)) {
                return;
            }

            //默认黑名单不通过
            WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(micaTransDto.getMerId(), micaFriendTalkMsg.getSendWxId());
            if(wwCustomerBlacklist != null){ //在黑名单中
                log.info("黑名单会员，wxid={}", micaFriendTalkMsg.getSendWxId());
                return ;
            }


            if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                log.info("机器人wxid is null, merId={}", micaTransDto.getMerId());
                return;
            }

            //查询该机器人的配置方案
            WwDevice wwDevice = wwDeviceMapper.queryByDeviceId(micaTransDto.getDeviceId(), micaTransDto.getMerId());
            if (wwDevice == null) {
                return;
            }
            Device device = DeviceTools.transDevice(wwDevice);
            if (device == null) {
                return;
            }

            //只支持文本消息
            if (micaFriendTalkMsg.getMsgType().intValue() != MicaTalkMsgType.TEXT.getCode().intValue()) {
                return;
            }

            //查询该会员信息
            WwCustomer wwCustomer = wwCustomerMapper.queryByDeviceUniqueIdAndWxid(device.getDeviceUniqueId(), sendWxId);
            if (wwCustomer == null) {
                return;
            }

            //获取文本消息
            MicaTalkContentTextMsg textContent = micaFriendTalkMsg.getTextContent();
            if (textContent == null) {
                return;
            }

            String text = textContent.getText();
            if (StringUtils.isBlank(text)) {
                return;
            }

            //查询该机器人配置的关键词拉群列表
            List<GroupPullConfigDevice> groupPullConfigDeviceList = groupPullConfigDeviceMapper.selectByDeviceUniqueIdAndType(1, device.getDeviceUniqueId(), device.getMerId());
            if (groupPullConfigDeviceList == null || groupPullConfigDeviceList.size() == 0) {
                log.info("未找到该机器人的关键词拉群方案，device={}, merId={}", micaTransDto.getDeviceId(), micaTransDto.getMerId());
                return;
            }

            //条件验证
            for (GroupPullConfigDevice groupPullConfigDevice : groupPullConfigDeviceList) {
                try {
                    //拉群方案
                    GroupPullConfig groupPullConfig = groupPullConfigMapper.selectById(groupPullConfigDevice.getPlanId());
                    if (groupPullConfig != null) {

                        //验证休眠时间
                        OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(groupPullConfigDevice.getRule(), OperatorPlanDeviceRule.class);
                        //此时属于休眠时间
                        boolean sleepTimeFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
                        if(sleepTimeFlag){
                            continue;
                        }
                        //验证一天内是否已经拉过群了
                        String key = String.format(LimitRedisCacheKeyEnum.LIMIT_GROUP_PULL_CONFIG.getKey(), groupPullConfig.getId(), sendWxId);
                        Object object = redisTemplate.opsForValue().get(key);
                        if (object != null) {
                            log.info("该客户当天已经触发此规则拉群，device={}, sendWxId={}, confidId={}", micaTransDto.getDeviceId(), sendWxId, groupPullConfig.getId());
                            //continue;
                        }

                        List<String> keywordList = JSONObject.parseArray(groupPullConfig.getKeywords(), String.class);
                        if (keywordList != null && keywordList.size() > 0) {
                            if (keywordList.contains(text)) {//触发关键词，拉群管理
                                if (Tools.getInteger(groupPullConfig.getModel()).intValue() == 1) { //单客户拉群
                                    groupPullByOne(groupPullConfig, wwCustomer, device);
                                } else { //多客户拉群
                                    //拉群规则
                                    List<GroupPullData> groupPullDataList = JSONObject.parseArray(groupPullConfig.getGuider(), GroupPullData.class);
                                    //封装拉群数据
                                    List<GroupPullMsgData> groupPullMsgDataList = groupPullDataService.handGroupPullData(groupPullConfig.getMerId(), groupPullDataList, wwCustomer, device);
                                    if (groupPullMsgDataList != null && groupPullMsgDataList.size() > 0) {
                                        //发送拉群消息
                                        msgSendService.groupPullMsgSend(device.getMerId(), device, wwCustomer, groupPullMsgDataList, groupPullConfig.getType(), groupPullConfig.getId(), false, null, MicaMsgSource.KEYWORD_PULL_GROUP.getCode(), micaFriendTalkMsg.getGroup());
                                        //设置缓存,一天内只触发一次
                                        redisTemplate.opsForValue().set(key, groupPullConfig.getId(), 1, TimeUnit.DAYS);
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }

        }catch (Exception e){
            log.error(e.getMessage(), e);
        }finally {
            log.info("--监控系统日志--结束--");
        }

    }

    @Override
    public void groupPushByEnterpriseTag(Device device, WwCustomer wwCustomer, Long tagId) {
        //根据标签拉群
        MicaTransDto micaTransDto1 = new MicaTransDto();
        micaTransDto1.setMerId(device.getMerId());
        micaTransDto1.setDeviceId(device.getDeviceId());
        MicaCustomerAddTagMsg micaCustomerAddTagMsg = new MicaCustomerAddTagMsg();
        micaCustomerAddTagMsg.setWxid(wwCustomer.getWxid());
        micaCustomerAddTagMsg.setId(tagId);
        micaCustomerAddTagMsg.setType(1);
        micaTransDto1.setData(micaCustomerAddTagMsg);
        this.groupPushByTag(micaTransDto1);
    }
    /**
     * 标签拉群
     *
     * @param micaTransDto
     * @return null
     * @author jitwxs
     * @date 2024/3/8 17:12
     */
    @Async("taskExecutorForEvent")
    @TraceGenerate //注入消息id标签
    public void groupPushByTag(MicaTransDto micaTransDto) {
        try {

            log.info("--监控系统日志--开始--");

            MicaCustomerAddTagMsg micaCustomerAddTagMsg = JSONObject.parseObject(JSONObject.toJSONString(micaTransDto.getData()), MicaCustomerAddTagMsg.class);
            if (micaCustomerAddTagMsg == null) {
                return;
            }

            //发送者微信id
            String sendWxId = micaCustomerAddTagMsg.getWxid();
            //标签id
            Long id = micaCustomerAddTagMsg.getId();
            if (id == null) {
                return;
            }
            //查询标签信息
            log.info("--监控系统日志--查询标签信息--");
            WwTags wwTags = wwTagsMapper.queryById(id);
            if (wwTags == null) {
                return;
            }

            //默认黑名单不通过
            log.info("--监控系统日志--查询黑名单--");
            WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(micaTransDto.getMerId(), sendWxId);
            if(wwCustomerBlacklist != null){ //在黑名单中
                log.info("黑名单会员，wxid={}", sendWxId);
                return ;
            }

            //标签类型(企微标签-1，个人标签-2)
            Integer type = micaCustomerAddTagMsg.getType();
            if (type == null) {
                return;
            }

            //只处理企微标签
            if (type.intValue() == 2) {
                return;
            }

            if (StringUtils.isBlank(sendWxId)) {
                return;
            }

            if (StringUtils.isBlank(micaTransDto.getDeviceId())) {
                log.info("机器人wxid is null, merId={}", micaTransDto.getMerId());
                return;
            }

            //查询该机器人的配置方案
            log.info("--监控系统日志--查询机器人--");
            WwDevice wwDevice = wwDeviceMapper.queryByDeviceId(micaTransDto.getDeviceId(), micaTransDto.getMerId());
            if (wwDevice == null) {
                return;
            }
            Device device = DeviceTools.transDevice(wwDevice);
            if (device == null) {
                return;
            }

            //查询该会员信息
            log.info("--监控系统日志--会员信息--");
            WwCustomer wwCustomer = wwCustomerMapper.queryByDeviceUniqueIdAndWxid(device.getDeviceUniqueId(), sendWxId);
            if (wwCustomer == null) {
                return;
            }

            //查询该机器人配置的标签拉群列表
            log.info("--监控系统日志--查询该机器人配置的标签拉群列表--");
            List<GroupPullConfigDevice> groupPullConfigDeviceList = groupPullConfigDeviceMapper.selectByDeviceUniqueIdAndType(2, device.getDeviceUniqueId(), device.getMerId());
            if (groupPullConfigDeviceList == null || groupPullConfigDeviceList.size() == 0) {
                log.info("未找到该机器人的关键词拉群方案，device={}, merId={}", micaTransDto.getDeviceId(), micaTransDto.getMerId());
                return;
            }

            //条件验证
            for (GroupPullConfigDevice groupPullConfigDevice : groupPullConfigDeviceList) {
                try {
                    //拉群方案
                    GroupPullConfig groupPullConfig = groupPullConfigMapper.selectById(groupPullConfigDevice.getPlanId());
                    if (groupPullConfig != null) {

                        //验证休眠时间
                        OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(groupPullConfigDevice.getRule(), OperatorPlanDeviceRule.class);
                        //此时属于休眠时间
                        boolean sleepTimeFlag = SleepTimeTools.verifySleepTime(operatorPlanDeviceRule);
                        if(sleepTimeFlag){
                            continue;
                        }

                        //验证一天内是否已经拉过群了
                        String key = String.format(LimitRedisCacheKeyEnum.LIMIT_GROUP_PULL_CONFIG.getKey(), groupPullConfig.getId(), sendWxId);
                        Object object = redisTemplate.opsForValue().get(key);
                        if (object != null) {
                            log.info("该客户当天已经触发此规则拉群，device={}, sendWxId={}, confidId={}", micaTransDto.getDeviceId(), sendWxId, groupPullConfig.getId());
                            //return;
                        }

                        List<Long> tagIdList = JSONObject.parseArray(groupPullConfig.getTags(), Long.class);
                        if (tagIdList != null && tagIdList.size() > 0) {
                            if (tagIdList.contains(wwTags.getId())) {//触发关键词，拉群管理
                                if (Tools.getInteger(groupPullConfig.getModel()).intValue() == 1) { //单客户拉群
                                    groupPullByOne(groupPullConfig, wwCustomer, device);
                                } else { //多客户拉群
                                    //拉群规则
                                    List<GroupPullData> groupPullDataList = JSONObject.parseArray(groupPullConfig.getGuider(), GroupPullData.class);
                                    //封装拉群数据
                                    List<GroupPullMsgData> groupPullMsgDataList = groupPullDataService.handGroupPullData(groupPullConfig.getMerId(), groupPullDataList, wwCustomer, device);
                                    if (groupPullMsgDataList != null && groupPullMsgDataList.size() > 0) {
                                        //发送拉群消息
                                        msgSendService.groupPullMsgSend(device.getMerId(), device, wwCustomer, groupPullMsgDataList, groupPullConfig.getType(), groupPullConfig.getId(), false, null, MicaMsgSource.TAG_PULL_GROUP.getCode(), false);
                                        //设置缓存,一天内只触发一次
                                        redisTemplate.opsForValue().set(key, groupPullConfig.getId(), 1, TimeUnit.DAYS);
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
        }catch (Exception e){
            log.error(e.getMessage(), e);
        }finally {
            log.info("--监控系统日志--结束--");
        }
    }


    /**
     * 处理单客户拉群
     *
     * @param groupPullConfig
     * @param wwCustomer
     * @param device
     * @author jitwxs
     * @date 2024/4/7 20:41
     */
    public void groupPullByOne(GroupPullConfig groupPullConfig, WwCustomer wwCustomer, Device device) {

        //验证是否已经达到上限
        Integer dayMax = Tools.getInteger(groupPullConfig.getDayMax());
        //获取当天的自动通过人数缓存
        String day_max_Key = String.format(LimitRedisCacheKeyEnum.LIMIT_GROUP_PULL_DAY_MAX.getKey(), groupPullConfig.getId());
        Integer day_max_Key_redis = (Integer) redisTemplate.opsForValue().get(day_max_Key);
        day_max_Key_redis = Tools.getInteger(day_max_Key_redis);
        //如果缓存中保持的上限已经大于等于配置的数量，则表示已经达到上限
        if (day_max_Key_redis >= dayMax) {
            log.info("此配置当天单客户拉群已经达到上限，planId={}, auto_audit_count_redis={}", groupPullConfig.getId(), day_max_Key_redis);
            return;
        }

        //单客户拉群群名
        String groupName = groupPullConfig.getGroupName();
        //替换[微信称呼/昵称]变量，优先称呼，在昵称
        String sendNickname = wwCustomer.getNickname();
        if (StringUtils.isBlank(sendNickname)) {
            sendNickname = wwCustomer.getName();
        }
        groupName = groupName.replace("[微信称呼/昵称]", Tools.getStr(sendNickname))
                .replace("[当前备注]", Tools.getStr(wwCustomer.getRemark()));

        //预设群成员
        List<String> memberWxidList = new ArrayList<>();
        memberWxidList.add(wwCustomer.getWxid());

        //预设成员
        List<GroupRule> groupRuleList = JSONObject.parseArray(groupPullConfig.getGroupRules(), GroupRule.class);
        if (groupRuleList != null && groupRuleList.size() > 0) {
            for (GroupRule groupRule : groupRuleList) {
                if (groupRule.getDeviceUniqueId().longValue() == device.getId().longValue()) {
                    List<Long> customerIdList = groupRule.getCustomerIds();
                    if (customerIdList != null && customerIdList.size() > 0) {
                        for (Long customerId : customerIdList) {
                            WwCustomer wwCustomer_member = wwCustomerMapper.queryById(customerId);
                            if (wwCustomer_member != null) {
                                String wxid = wwCustomer_member.getWxid();
                                memberWxidList.add(wxid);
                            }
                        }
                    }

                }
            }
        }

        //发送创建群指令
        MicaTriggerGroupAddMsg micaTriggerGroupAddMsg = new MicaTriggerGroupAddMsg();
        micaTriggerGroupAddMsg.setGroupName(groupName);
        micaTriggerGroupAddMsg.setWxIds(StringUtils.join(memberWxidList, ";"));
        MicaTriggerDto micaTriggerDto = MicaTriggerDto.newInstance(micaTriggerGroupAddMsg, MicaTriggerType.TRIGGER_GROUP_ADD, Functions.fillTriggerMsg(device));
        sendMsgProducer.pushMsg(micaTriggerDto, MicaTopics.WW_TRIGGER_TOPIC); //存放瞬时消息

        //保存当天建群最大数+1
        //计算当前时间与次日凌晨的差值
        long leftTime = Tools.getSecondsTobeforedawn();
        //更新缓存
        redisTemplate.opsForValue().increment(day_max_Key);
        redisTemplate.expire(day_max_Key, leftTime, TimeUnit.SECONDS);
    }

}
